package crmdna.registration;

import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import crmdna.common.APIException;
import crmdna.common.APIResponse;
import crmdna.common.APIResponse.Status;
import crmdna.common.Utils;

@SuppressWarnings("serial")
public class RegistrationServlet extends HttpServlet {

	public void doOptions(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		resp.setHeader("Access-Control-Allow-Origin", "*");
		resp.setHeader("Access-Control-Allow-Methods", "POST");
		resp.setHeader("Access-Control-Allow-Headers", "Content-Type");
		resp.setHeader("Access-Control-Max-Age", "86400");
		resp.setHeader("Allow", "POST, OPTIONS");
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		try {

			String client = req.getParameter("client");

			String firstName = req.getParameter("firstName");

			String lastName = req.getParameter("lastName");
			if ((lastName != null) && lastName.equals(""))
				lastName = null;

			String nickName = req.getParameter("nickName");
			if ((nickName != null) && nickName.equals(""))
				nickName = null;

			String gender = req.getParameter("gender");
			if ((gender != null) && gender.equals(""))
				gender = null;

			String email = req.getParameter("email");

			String mobilePhone = req.getParameter("mobilePhone");
			if ((mobilePhone != null) && mobilePhone.equals(""))
				mobilePhone = null;

			String homePhone = req.getParameter("homePhone");
			if ((homePhone != null) && homePhone.equals(""))
				homePhone = null;

			String officePhone = req.getParameter("officePhone");
			if ((officePhone != null) && officePhone.equals(""))
				officePhone = null;

			String postalCode = req.getParameter("postalCode");
			if ((postalCode != null) && postalCode.equals(""))
				postalCode = null;

			String country = req.getParameter("country");
			if ((country != null) && country.equals(""))
				country = null;

			String marketingChannel = req.getParameter("marketingChannel");
			if ((marketingChannel != null) && marketingChannel.equals(""))
				marketingChannel = null;

			String programIdStr = req.getParameter("programId");

			String feeStr = req.getParameter("feeStr");
			if ((feeStr != null) && feeStr.equals(""))
				feeStr = null;

			String batchNoStr = req.getParameter("batchNo");
			if ((batchNoStr != null) && batchNoStr.equals(""))
				batchNoStr = null;

			String successCallbackUrl = req.getParameter("successCallbackUrl");

			String errorCallbackUrl = req.getParameter("errorUrl");
			if ((errorCallbackUrl != null) && errorCallbackUrl.equals(""))
				errorCallbackUrl = null;

			String sandoxStr = req.getParameter("sandbox");
			boolean sandbox = false;
			if ((sandoxStr != null) && sandoxStr.toUpperCase().equals("TRUE"))
				sandbox = true;

			String rootUrl = req.getRequestURL().toString();

			RegistrationProp registrationProp = Registration.register(client,
					firstName, lastName, nickName, gender, email, mobilePhone,
					homePhone, officePhone, country, postalCode, programIdStr,
					feeStr, batchNoStr, marketingChannel, successCallbackUrl,
					errorCallbackUrl, rootUrl, sandbox);

			switch (registrationProp.getStatus()) {
			case REGISTRATION_COMPLETE:
				Map<String, Object> map = new TreeMap<>();

				map.put("email", registrationProp.email);
				map.put("timestamp", registrationProp.getStatusTimestamp());
				map.put("firstName", registrationProp.firstName);
				map.put("registrationId", registrationProp.registrationId + "");

				if (registrationProp.lastName != null)
					map.put("lastName", registrationProp.lastName);

				if (registrationProp.transactionId != null)
					map.put("transactionId", registrationProp.transactionId);

				map.put("status", registrationProp.getStatus());
				map.put("timestamp", registrationProp.getStatusTimestamp());

				String redirectUrl;
				if (registrationProp.alreadyRegistered) {
					map.put("alreadyRegistered", true);
					redirectUrl = Utils.getUrl(
							registrationProp.errorCallbackUrl, map);
				} else {
					redirectUrl = Utils.getUrl(
							registrationProp.successCallbackUrl, map);
				}

				resp.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
				Utils.ensureValidUrl(redirectUrl);
				Logger logger = Logger.getLogger(RegistrationServlet.class
						.getName());
				logger.info("redirect URL [" + redirectUrl + "]");
				resp.setHeader("Location", redirectUrl);
				break;

			case PAYMENT_AUTHORIZATION_PENDING:
				resp.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
				Utils.ensureValidUrl(registrationProp.paymentUrl);
				resp.setHeader("Location", registrationProp.paymentUrl);
				break;
			default:
				// should never come here
				throw new APIException(
						Status.ERROR_INTERNAL,
						"Invalid registration status ["
								+ registrationProp.getStatus()
								+ "] in RegistrationServlet after call to register.");
			}
		} catch (Exception ex) {
			APIResponse apiResponse = new APIResponse(ex);
			String errMessage = "An error occurred. Please try again.\n\n"
					+ "Error code: " + apiResponse.statusCode + "\nMessage: "
					+ apiResponse.userFriendlyMessage + "\n\nStack trace: "
					+ apiResponse.object;
			Logger logger = Logger.getLogger(RegistrationServlet.class
					.getName());
			logger.warning(errMessage);
			resp.getWriter().println(errMessage);
		}
	}
}